
if (!window.sao_tool) {

  sao_tool = {
    copyToClipboard(text) {
      // 存储到数组

      // 创建一个隐藏的 textarea 元素
      const textarea = document.createElement('textarea');

      // 将待复制的文本设置为 textarea 的值
      textarea.value = text;

      // 将 textarea 元素加入到 DOM 中
      document.body.appendChild(textarea);

      // 选中 textarea 中的文本
      textarea.select();

      // 执行复制操作
      try {
        document.execCommand('copy');
        console.log('Text copied to clipboard');
      } catch (err) {
        console.error('Failed to copy text: ', err);
      }

      // 复制后移除 textarea 元素
      document.body.removeChild(textarea);
    },
    DrissionPageParser: {
      _getDpValue(element) {

        // 获取元素的 tagName、id 和 textContent
        let tagName = element.tagName.toLowerCase();
        // 将 tagName 转换为小写
        // 排除一些不需要的标签
        if (tagName == 'body' || tagName == 'header' || tagName == 'style' || tagName == 'script') {
          element.dp = '跳过';
          return false;
        }

        let txt = element.innerText;
        // 排除一些没有的文本的元素    
        let textContent = txt == '' ? '' : '@@tx()=' + txt;

        // 构建属性部分
        let attributes = '';
        Array.from(element.attributes).forEach(function (attr) {
          // 每个属性的格式为 name=value
          let attr_info = `@@${attr.name}=${attr.value}`;
          // 排除一些不需要的属性
          if (attr.name == 'src' || attr.name == 'href')
            attr_info = '';
          attributes += attr_info;
        });

        // 格式化 dp 值
        let dpValue = `t:${tagName}${attributes}${textContent}`;

        // 设置 dp 属性
        // element.dp = dpValue;
        return dpValue;

      },
      getDpValue(element) {
        if (element) { return this._getDpValue(element); }
        else {
          return "error!";
        }

      },


    },

    XPathParser: {
      // 检查 XPath 是否唯一
      isUniqueXPath: function (xpath) {
        const result = document.evaluate(
          xpath,
          document,
          null,
          XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,
          null
        );
        return result.snapshotLength === 1;
      },

      // 查找包含唯一 id 的祖先元素
      findAncestorWithUniqueId: function (element) {
        return $(element).parents().filter(function () {
          return $(this).attr('id');
        }).first()[0] || null;
      },

      // 获取在祖先元素内的路径
      getPathWithinAncestor: function (ancestor, element) {
        let path = '';
        while (element && element !== ancestor) {
          const tagWithPosition = this.getTagWithPosition(element);
          path = `/${tagWithPosition}${path}`;
          element = element.parentElement;
        }
        return path;
      },

      // 获取元素标签和兄弟元素的索引
      getTagWithPosition: function (element) {
        const tagName = $(element).prop('tagName').toLowerCase();
        const siblings = $(element).parent().children(tagName);
        const index = siblings.index(element) + 1;  // jQuery's index() is zero-based
        return `${tagName}[${index}]`;
      },
      // 主要入口
      getXPath: function (element) {
        try {
          let xpath = this.getOptimalXPath(element);
          return xpath;
        } catch (error) {
          // console.log('Error in getXPath:', error);
          return "error!";
        }
      },

      // 获取最优 XPath
      getOptimalXPath: function (element, depth = 0, MAX_DEPTH = 12) {
        if (!element || depth > MAX_DEPTH) return null;

        const tagName = $(element).prop('nodeName').toLowerCase();

        // 1. 优先使用唯一的 ID
        if ($(element).attr('id') && this.isUniqueXPath(`//${tagName}[@id="${$(element).attr('id')}"]`)) {
          return `//${tagName}[@id="${$(element).attr('id')}"]`;
        }

        let className = $(element).attr('class') || '';
        className = className.replace(/outline-selector|highlight-selector/g, '').trim();

        // 2. 使用类名和属性，找到匹配的元素
        if (className && this.isUniqueXPath(`//${tagName}[contains(@class, "${className}")]`)) {
          return `//${tagName}[contains(@class, "${className}")]`;
        }

        const ancestorWithId = this.findAncestorWithUniqueId(element);
        if (ancestorWithId) {
          const idTagName = $(ancestorWithId).prop('nodeName').toLowerCase();
          const ancestorXPath = `//${idTagName}[@id="${$(ancestorWithId).attr('id')}"]`;
          const pathWithinAncestor = this.getPathWithinAncestor(ancestorWithId, element);
          return `${ancestorXPath}${pathWithinAncestor}`;
        }

        const tableAncestor = this.findAncestorTable(element);
        if (tableAncestor) {
          const tablePath = this.getTableXPath(tableAncestor, depth + 1, MAX_DEPTH);
          const elementPath = this.getPathWithinTable(tableAncestor, element);
          return `${tablePath}${elementPath.startsWith('//') ? elementPath.substring(1) : elementPath}`;
        }

        // 3. 优先使用唯一的文本内容
        const trimmedText = $(element).text().trim().replace(/\s+/g, ' ');
        if (trimmedText && this.isUniqueXPath(`//${tagName}[text()="${trimmedText}"]`)) {
          return `//${tagName}[text()="${trimmedText}"]`;
        }

        // 4. 最后使用索引

        return this.getElementXPathByIndex(element);
      },

      getElementXPathByIndex: function (element) {
        let xpath = '';
        while (element && element.nodeType === Node.ELEMENT_NODE) {
          let index = 1;
          let sibling = element.previousSibling;
          while (sibling) {
            if (sibling.nodeType === Node.ELEMENT_NODE && sibling.nodeName === element.nodeName) {
              index++;
            }
            sibling = sibling.previousSibling;
          }
          const tagName = element.nodeName.toLowerCase();
          xpath = `/${tagName}[${index}]` + xpath;
          element = element.parentNode;
        }
        return xpath;
      },

      // 查找表格元素祖先
      findAncestorTable: function (element) {
        return $(element).parents().filter(function () {
          return $(this).prop('tagName').toLowerCase() === 'table';
        }).first()[0] || null;
      },

      // 获取表格 XPath
      getTableXPath: function (tableElement, depth, MAX_DEPTH) {
        if (depth > MAX_DEPTH) return '';
        const tagName = $(tableElement).prop('tagName').toLowerCase();
        const siblings = $(tableElement).parent().children(tagName);
        const index = siblings.index(tableElement) + 1;
        return `//${tagName}[${index}]`;
      },

      // 获取表格内元素的路径
      getPathWithinTable: function (tableElement, element) {
        let path = '';
        while (element && element !== tableElement) {
          const tagWithPosition = this.getTagWithPosition(element);
          path = `/${tagWithPosition}${path}`;
          element = element.parentElement;
        }
        return path;
      }
    },
    loadJquery() {
      if (typeof jQuery == 'undefined') {
        var script = document.createElement('script');
        script.src = 'https://code.jquery.com/jquery-3.6.0.min.js'; // 使用 CDN 导入 jQuery
        script.type = 'text/javascript';
        script.onload = function() {
          console.log('jQuery 已成功加载');
        };
        script.onerror = function() {
          console.error('jQuery 加载失败');
        };
        document.head.appendChild(script);
      } else {
        // console.log('jQuery 已经加载');
      }
    }
    
  },
  sao_tool.loadJquery();

}




if (window.__ele==undefined) {

  window.__ele = document.body;
  // 监听鼠标移动事件，获取鼠标所在元素
  document.addEventListener('mousemove', (event) => {
    window.__ele = document.elementFromPoint(event.clientX, event.clientY);
  });

  // 监听键盘按下事件，按下 "F2" 键时打印当前鼠标所在的元素
  document.addEventListener('keydown', (event) => {
    let e=window.__ele;
    if (event.key === "F2" && e) {
      let a = sao_tool.DrissionPageParser.getDpValue(e);
      console.log("dp   语法捕获:", a);
      sao_tool.copyToClipboard(a);
    }
    if (event.key === "F4" && e) {
      let a = sao_tool.XPathParser.getXPath(e);
      console.log("xpath语法捕获:", a);
      sao_tool.copyToClipboard(a); 
    }
    if (event.key === "F9" && e) {
      
      console.log("当前鼠标指针所在的元素:", e);
     
    }
  });
}





